package com.framework.common.util.minio;

import com.framework.common.enums.annex.GroupStatusEnum;
import io.minio.BucketExistsArgs;
import io.minio.DeleteBucketPolicyArgs;
import io.minio.GetBucketPolicyArgs;
import io.minio.GetObjectArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveBucketArgs;
import io.minio.RemoveObjectArgs;
import io.minio.SetBucketPolicyArgs;
import io.minio.http.Method;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.InputStream;

/**
 * @author 龘鵺
 * @className com.framework.common.util.minio
 * @description 文件服务器工具类
 * @datetime 2024-12-12 13:46:05
 * @version 1.0
 */
@Component(value = "minioUtil")
public class MinioUtil {
    //桶名称
//    @Value("${custom.minio.bucketName}")
//    private String bucketName;
    @Autowired
    private MinioClient minioClient;
    /**
     * @title 规则前缀
     * @description 规则前缀
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String ARN_AWS_S3 = "arn:aws:s3:::";
    /**
     * @title 替换桶名称
     * @description 替换桶名称
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String BUCKET_NAME_PARAM = "\\$\\{bucketName\\}";
    /**
     * @title 只读
     * @description 只读
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String READONLY_PARAM = "${readonly}";
    /**
     * @title 只写
     * @description 只写
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String WRITEONLY_PARAM = "${writeonly}";
    /**
     * @title 读写
     * @description 读写
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String READ_WRITE_PARAM = "${readwrite}";
    /**
     * @title 主内容
     * @description 主内容
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String READWRITE_CONTENT = "${content}";

    /**
     * @title 总内容
     * @description 总内容
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String TOTAL_CONTENT = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::${bucketName}\"]}${content}]}";
    /**
     * @title 只读内容
     * @description 只读内容
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String READ_CONTENT = "{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\"],\"Resource\":${readonly}}";
    /**
     * @title 只写内容（包含删除）
     * @description 只写内容（包含删除）
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String WRITE_CONTENT = "{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":${writeonly}}";
    /**
     * @title 读写内容（包含删除）
     * @description 读写内容（包含删除）
     * @author 龘鵺
     * @datetime 2024-12-12 15:47:49
     */
    public final static String READ_WRITE_CONTENT = "{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":${readwrite}}";


    private String getBucket(String bucket) {
//        if (bucket.lastIndexOf(minioSuffix) == NumeralUtil.NEGATIVE_ONE) {
//            return bucket + minioSuffix;
//        }
        return bucket;
    }

    /**
     * @param bucket 1 桶名称
     * @return java.lang.String 策略字符串
     * @title 查看策略
     * @description 查看策略
     * @author 龘鵺
     * @datetime 2024-12-12 13:46:05
     */
    public String getBucketPolicy(String bucket) throws Exception {
        String policy = minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket("home-page-carousel-clientuser-local-mall").build());
        return policy;
    }

    /**
     * @param bucket 1 创建目录名称
     * @title 创建一个桶, 也就是创建一个文件夹
     * @description 创建一个桶, 也就是创建一个文件夹
     * @author 龘鵺
     * @datetime 2024-12-12 13:46:05
     */
    public void createBucket(String bucket) throws Exception {
//        if (StringUtils.isEmpty(minioSuffix)) {
//            throw new RuntimeException("目录后缀名不能为空!");
//        }
        //判断当前文件夹是否存在
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(getBucket(bucket)).build());
        if (!found) {
            //不存在进行创建
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(getBucket(bucket)).build());
        }
    }

    /**
     * @param bucket          1 桶名称
     * @param groupStatusEnum 2 设置状态
     * @title 设置minio桶状态
     * @description 设置minio桶状态
     * @author 龘鵺
     * @datetime 2024-12-12 13:46:05
     */
    public void setBucketPolicy(String bucket, GroupStatusEnum groupStatusEnum) throws Exception {
//        if (StringUtils.isEmpty(minioSuffix)) {
//            throw new RuntimeException("目录后缀名不能为空!");
//        }
//        if (bucket.lastIndexOf(minioSuffix) == NumeralUtil.NEGATIVE_ONE) {
//            bucket = bucket + minioSuffix;
//        }
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(getBucket(bucket)).build());
        if (found) {
            minioClient.deleteBucketPolicy(DeleteBucketPolicyArgs.builder().bucket(getBucket(bucket)).build());
            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(getBucket(bucket))
                    .config(groupStatusEnum.getContent().replaceAll(BUCKET_NAME_PARAM, bucket)).build());
        }
    }

    public void setBucketPolicy(String bucket, String content) throws Exception {
//        if (StringUtils.isEmpty(minioSuffix)) {
//            throw new RuntimeException("目录后缀名不能为空!");
//        }
//        if (bucket.lastIndexOf(minioSuffix) == NumeralUtil.NEGATIVE_ONE) {
//            bucket = bucket + minioSuffix;
//        }
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(getBucket(bucket)).build());
        if (found) {
            minioClient.deleteBucketPolicy(DeleteBucketPolicyArgs.builder().bucket(getBucket(bucket)).build());

            try {
                content = content.replaceAll(BUCKET_NAME_PARAM, bucket);
                System.out.println(content);
                minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(getBucket(bucket))
                        .config(content).build());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * @param stream     1 输入流
     * @param bucket     2 创建目录名称
     * @param objectName 3 文件名
     * @title 上传一个文件
     * @description 上传一个文件
     * @author 龘鵺
     * @datetime 2024-12-12 13:46:05
     */
    public void uploadFile(InputStream stream, String bucket, String objectName) throws Exception {
//        if (bucket.lastIndexOf(minioSuffix) == NumeralUtil.NEGATIVE_ONE) {
//            bucket = bucket + minioSuffix;
//        }
        try {
            minioClient.putObject(PutObjectArgs.builder().bucket(getBucket(bucket)).object(objectName)
//                .stream(stream, -1, 10485760).build());
                    .stream(stream, -1, 5242880).build());
        } catch (Exception e) {
            throw e;
        } finally {
            IOUtils.closeQuietly(stream);
        }
    }

    /**
     * @param bucket     1 创建目录名称
     * @param objectName 2 文件名
     * @title 下载一个文件
     * @description 下载一个文件
     * @author 龘鵺
     * @datetime 2024-12-12 13:46:05
     */
    public InputStream download(String bucket, String objectName) throws Exception {
//        if (bucket.lastIndexOf(minioSuffix) == NumeralUtil.NEGATIVE_ONE) {
//            bucket = bucket + minioSuffix;
//        }
        InputStream stream = minioClient.getObject(
                GetObjectArgs.builder().bucket(getBucket(bucket)).object(objectName).build());
        return stream;
    }

    /**
     * @param bucket 1 创建目录名称
     * @title 删除一个桶
     * @description 删除一个桶
     * @author 龘鵺
     * @datetime 2024-12-12 13:46:05
     */
    public void deleteBucket(String bucket) throws Exception {
//        if (bucket.lastIndexOf(minioSuffix) == NumeralUtil.NEGATIVE_ONE) {
//            bucket = bucket + minioSuffix;
//        }
        minioClient.removeBucket(RemoveBucketArgs.builder().bucket(getBucket(bucket)).build());
    }

    /**
     * @param bucket     1 创建目录名称
     * @param objectName 2 文件名
     * @title 删除一个对象
     * @description 删除一个对象
     * @author 龘鵺
     * @datetime 2024-12-12 13:46:05
     */
    public void deleteObject(String bucket, String objectName) throws Exception {
//        if (bucket.lastIndexOf(minioSuffix) == NumeralUtil.NEGATIVE_ONE) {
//            bucket = bucket + minioSuffix;
//        }
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(getBucket(bucket)).object(objectName).build());
    }

    /**
     * @param method     1 方法格式
     * @param bucket     2 创建目录名称
     * @param objectName 3 文件名
     * @return java.lang.String
     * @title 获取URL
     * @description 获取URL
     * @author 龘鵺
     * @datetime 2024-12-12 13:46:05
     */
    public String getUrl(Method method, String bucket, String objectName) throws Exception {
//        GetPresignedObjectUrlArgs.builder().expiry(1, TimeUnit.MINUTES).method(method).bucket(getBucket(bucket)).object(objectName).build();
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                .method(method)
                .bucket(getBucket(bucket))
                .object(objectName)
                .expiry(60 * 60 * 24)
                .build());
    }
}
